/*
 * Copyright (C) 2009 Juan Alberto López Cavallotti
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package networking;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.UUID;
import parameters.ParameterFacade;
import parameters.Profile;

/**
 * Coordinates all the stuff to be done using a network.
 * @author juan
 */
public class NetworkingCore implements ServiceProvider {

    //singleton
    private static NetworkingCore instance = new NetworkingCore();
    private Protocol defaultProtocol;
    private Profile profile;
    private DatagramSocket bcastSock;
    private ServerSocket incomingSock;
    private Socket clientSock;


    public static NetworkingCore getInstance() {
        return instance;
    }



    private NetworkingCore() {
        
    }

    public void startService() throws NetworkingException {
        
        //open the broadcast socket
        openBcastSock();

        //listen to conections
        openIncomingSock();

        int protocolVersion = ParameterFacade.getInstance().getProtocolVersion();
        defaultProtocol = ProtocolFactory.createProtocol(protocolVersion);
    }

    public void useProfile(Profile p) throws NetworkingException {
        this.profile = p;
    }

    public Profile createProfile(String name) throws NetworkingException {
        Profile p = defaultProtocol.requestProfile(name);

        if (p != null)
            //tirar una futura excepcion
            return null;

        p = new Profile();
        p.setName(name);
        p.setUuid(UUID.randomUUID().toString());
        defaultProtocol.sendCreateProfile(p);
        return p;
    }

    public void sendChatMessage(String userName, String message) throws NetworkingException {
        defaultProtocol.sendChatMessage(profile, userName, message);
    }

    private void openBcastSock() throws NetworkingException {
        try {
            bcastSock = new DatagramSocket(12450);
        } catch (SocketException ex) {
            throw new TransportLayerException("Error while opening broadcast socket", ex);
        }

    }

    private void openIncomingSock() throws NetworkingException {
        try {
            incomingSock = new ServerSocket(12451, 10);
        } catch (IOException ex) {
            throw new TransportLayerException("Unable to bind to the selected port", ex);
        }
    }
    
}
